<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        var arr = [23,[32,4,4,5,333,333],[333,2,[22,57]], 1];
        changeArr(arr);

        function changeArr(arr) {
            // 先深克隆数组
            var newArr = JSON.parse(JSON.stringify(arr));
            // 扁平化
            newArr =  flat(newArr);
            // 去重
            newArr = duplicates(newArr);
            // 排序
            // newArr.sort(function (a, b) {
            //     return a - b
            // })
            console.log(newArr);
        }

        function flat(arr) {
            var narr = [];
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] instanceof Array) {
                    narr =  narr.concat(flat(arr[i]));
                } else {
                    narr.push(arr[i]);
                }
            }
            return narr;
        }

        function duplicates(arr) {
            // 1. 创建一个新数组   遍历旧数组，看新数组中是否包含旧数组的项，不包含添加
            // 2. 遍历旧数组，查看数组中的项的下标是否等于xarr.indexOf(项)  不等于就删除
            // 3. 对象属性方式  遍历数组将数组项添加成对象的属性，遍历完成获取所有对象的属性（排序，数字会变成字符串）常用于统计数组中项的出现次数

            // 这是方法2
            /*for (var i = 0; i < arr.length; i++) {
                if (arr.indexOf(arr[i]) !== i) {
                    arr.splice(i--, 1);
                }
            }*/

            // 这是方法3
            var obj = {}
            var narr = []
            for (var i = 0; i < arr.length; i++) {
                obj[arr[i]] = obj[arr[i]] ? obj[arr[i]] + 1 : 1;
            }
            console.log(obj);
            for (var i in obj) {
                narr.push(Number(i))
            }
            return narr;
        }


        /*
            创建一个函数delay(fn, time)，返回一个延迟time ms执行的函数fn  函数装饰器
        */

        var f1 = delay(fn, 2000)
        f1('李白', 45)

        function fn(name, age) {
            console.log(name + 'can say: my age is ' + age);
        }

        function delay(fn, time) {
            return function (...args) {
                setTimeout(function () {
                    fn.call(this,...args)
                }, time)
            }
        }
    </script>
</body>
</html>